
#include "mlMat2.h"

namespace ml
{

	Mat2::Mat2(void)
	{
		Identity();
	}

	Mat2::Mat2(const Mat2 &a)
	{
		m00 = a.m00;
		m01 = a.m01;
		m10 = a.m10;
		m11 = a.m11;
	}

	Mat2::Mat2(float nm00, float nm01, float nm10, float nm11)
	{
		m00 = nm00;
		m01 = nm01;
		m10 = nm10;
		m11 = nm11;
	}

	Mat2::Mat2(float m[4])
	{
		m00 = m[0];
		m01 = m[1];
		m10 = m[2];
		m11 = m[3];
	}

	Mat2::Mat2(float m[2][2])
	{
		m00 = m[0][0];
		m01 = m[0][1];
		m10 = m[1][0];
		m11 = m[1][1];
	}

	Mat2::~Mat2(void)
	{
	}

	Mat2 &Mat2::operator =(const Mat2 &a)
	{
		m00 = a.m00;
		m01 = a.m01;
		m10 = a.m10;
		m11 = a.m11;
		return *this;
	}

	bool Mat2::operator ==(const Mat2 &a) const
	{
		return m00 == a.m00 && m01 == a.m01
			&& m10 == a.m10 && m11 == a.m11;
	}

	bool Mat2::operator !=(const Mat2 &a) const
	{
		return m00 != a.m00 || m01 != a.m01
			|| m10 != a.m10 || m11 != a.m11;
	}

	Mat2 Mat2::operator -(void) const
	{
		mMatrix2x2 m(*this);
		m.m00 *= -1;
		m.m01 *= -1;
		m.m10 *= -1;
		m.m11 *= -1;
		return m; 
	}

	Mat2 Mat2::operator +(const Mat2 &a) const
	{
		mMatrix2x2 m(*this);
		m.m00 += a.m00;
		m.m01 += a.m01;
		m.m10 += a.m10;
		m.m11 += a.m11;
		return m;
	}

	Mat2 Mat2::operator -(const Mat2 &a) const
	{
		mMatrix2x2 m(*this);
		m.m00 -= a.m00;
		m.m01 -= a.m01;
		m.m10 -= a.m10;
		m.m11 -= a.m11;
		return m;
	}

	Mat2 Mat2::operator *(const Mat2 &a) const
	{
		mMatrix2x2 m;
		m.m00 = (m00 * a.m00) + (m01 * a.m10);
		m.m01 = (m00 * a.m01) + (m01 * a.m11);
		m.m10 = (m10 * a.m00) + (m11 * a.m10);
		m.m11 = (m10 * a.m01) + (m11 * a.m11);
		return m;
	}

	Vec2 Mat2::operator *(const Vec2 &a) const
	{
		mVector2 v;
		v.X = (m00 * a.X) + (m01 * a.Y);
		v.Y = (m10 * a.X) + (m11 * a.Y);
		return v;
	}

	mMatrix2x2 mMatrix2x2::operator *(float a) const
	{
		mMatrix2x2 m(*this);
		m.m00 *= a;
		m.m01 *= a;
		m.m10 *= a;
		m.m11 *= a;
		return m;	
	}

	mMatrix2x2 &mMatrix2x2::operator +=(const mMatrix2x2 &a)
	{
		m00 += a.m00;
		m01 += a.m01;
		m10 += a.m10;
		m11 += a.m11;
		return *this;
	}

	mMatrix2x2 &mMatrix2x2::operator -=(const mMatrix2x2 &a)
	{
		m00 -= a.m00;
		m01 -= a.m01;
		m10 -= a.m10;
		m11 -= a.m11;
		return *this;
	}

	mMatrix2x2 &mMatrix2x2::operator *=(float a)
	{
		m00 *= a;
		m01 *= a;
		m10 *= a;
		m11 *= a;
		return *this;	
	}

	float &mMatrix2x2::operator [](int index)
	{
		switch (index)
		{
		case 0:
			return m00;
		case 1:
			return m01;
		case 2:
			return m10;
		case 3:
			return m11;
		default:
			return m00;
		}
	}

	void mMatrix2x2::Identity(void)
	{
		m00 = m11 = 1.0f;
		m01 = m10 = 0.0f;
	}

	// counterclockwise
	void mMatrix2x2::createRotation(float angle)
	{
		m00 = m11 = cos(angle);
		m01 = m10 = sin(angle);
		m01 *= -1;
	}

	void mMatrix2x2::createTranslation(mVector2 translation)
	{
	}

	void mMatrix2x2::createScale(float scale)
	{
		m00 = m11 = scale;
		m01 = m10 = 0.0f;
	}

}